using System;
using System.Collections.Generic;
using System.Text;

namespace Scheduler
{
    /*
     * An object of this class holds the information of a customer such as:
     * customer's name(Strign name)
     * customer's password (int passwd)
     * the list of the appoinments scheduled for this customer: 
     *                     (LinkedList<Appointment> appointmentList)
     * The total Balance of this customer's account(int Balance)
     */
    public class Customer
    {
        private String name;
        private String id;
        private LinkedList<Appointment> appointmentList;
        private int balance;

        public Customer()
        {
            name = "";
            id = "";
            balance = 0;
            appointmentList = new LinkedList<Appointment>();
        }

        public Customer(String givenName, String givenId)
        {
            name = givenName;
            id = givenId;
            balance = 0;
            appointmentList = new LinkedList<Appointment>();
        }

        public Customer(String givenName, String givenID, int balance)
        {
            name = givenName;
            id = givenID;
            this.balance = balance;
            appointmentList = new LinkedList<Appointment>();
        }

        public Customer(Database db, String customerID)
        {
            Customer temp = db.readCustomer(customerID);
            this.name = temp.Name;
            this.id = temp.ID;
            this.balance = temp.balance;
            this.appointmentList = temp.appointmentList;
        }
        public String Name
        {
            get { return name; }
            set { name = String.Copy(value); }
        }
        public String ID
        {
            get { return id; }
            set { id = String.Copy(value); }
        }

        public int Balance
        {
            get { return balance; }
            set { balance = value; }
        }

        public LinkedList<Appointment> AppointmentList
        {
            get { return appointmentList; }
        }

        /*
         * This method returns a String that contains detailed information of
         * all the appointments that exist in this customer's AppointmentList.
         * If the list is empty then this customer just gets a message informing him/her 
         * of his situation.
         */
        public String displayAppointments()
        {
            if (AppointmentList.Count == 0)
                return "You do not have any appointments booked. Your balance is: $" + this.Balance;

            String appointments = "";
            foreach (Appointment curApp in this.appointmentList)
            {
                appointments = appointments + curApp.ToString() + "\r\r\n";
            }
            return appointments + "\r\r\nYour total balance is: $" + this.Balance;
        }

        /*
         * This method adds a new appointment to the AppointmentList of this customer.
         * The information needed for the new appointment are taken as parameters to this method.
         */
        public void updateAppointments(Database db, String rmtName, String therName, String roomName, TimeSlot time, int price)
        {
            Appointment curApp = new Appointment(rmtName, therName, roomName, time, price);
            appointmentList.AddLast(curApp);
            this.Balance += price;
            curApp.ID = db.writeAppointment(curApp);
            this.writeToDatabase(db);
        }

        /*
         * This method cancels an appointment by finding and removind it from this customer's
         * AppointmentList and updating the balance.
         * The corresponding values of the appointment are taken as parameters.
         * If there is less than 24 hours left to the appointment, then a penalty of 1/2 price
         * will be added to the balance. Else there will be no penalty.
         */
        public int cancelAppointment(Database db, String therName, String rmtName, String roomName, TimeSlot time)
        {
            int penalty = -1;
            Appointment tempApp = new Appointment(rmtName, therName, roomName, time, 0);
            if (!AppointmentList.Contains(tempApp))
            {
                return penalty;
            }
            else
            {
                DateTime now = DateTime.Now;
                now.ToLongDateString();
                now = now.AddHours(24);
                now.ToLongDateString();
                DateTime appTime = AppointmentList.Find(tempApp).Value.Time.StartTime;
                if (DateTime.Compare(now, appTime) > 0)
                {
                    //less than 24 hours before appointment time, so 50% penalty!
                    penalty = (int)((AppointmentList.Find(tempApp).Value.Price) / 2);
                    this.Balance -= penalty;
                    appointmentList.Remove(AppointmentList.Find(tempApp));//can ask user if he/she really wants to cancel it at this point
                }
                else
                {
                    penalty = 0;
                    this.Balance -= AppointmentList.Find(tempApp).Value.Price;
                    appointmentList.Remove(AppointmentList.Find(tempApp));
                }

                db.removeAppointment(tempApp.ID);
                this.writeToDatabase(db);
                return penalty;
            }
        }
        public void writeToDatabase(Database db)
        {
            db.writeCustomer(this);
        }

        public void removeFromDatabase(Database db)
        {
            foreach (Appointment curApp in AppointmentList)
            {
                this.cancelAppointment(db, curApp.TherapyName, curApp.RMTName,
                                        curApp.Room, curApp.Time);
            }
            db.removeCustomer(this.ID);
        }
    }
}
